#pragma once
#include "Socket.hpp"
#include "Log.hpp"
#include <functional>
#include <sys/types.h>
#include <sys/wait.h>

namespace TcpServerModule
{
    using namespace LogModule;
    using namespace SocketModule;

    using handler_t = std::function<bool(SockPtr, InetAddr)>;
    class TcpServer
    {
    public:
        TcpServer(uint16_t port = defaultport)
            : _listensockfd(std::make_unique<TcpSocket>()), _isrunning(false)
            ,_port(port)
        {
        }
        void Init(handler_t handler)
        {
             _handler =handler;
            _listensockfd->BuildTcpSocketMethod(8080);
        }
        void Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                InetAddr inetaddr; // 输出型参数
                auto sockfd = _listensockfd->Accepter(&inetaddr);
                if (sockfd == nullptr)
                {
                    
                    continue;
                }
                    
                LOG(LogLevel::DEBUG) << "get a new client, info is: " << inetaddr.Addr();

                pid_t id = fork();
                if (id == 0)
                {
                    if (fork() > 0)
                    {
                        exit(0);
                    }
                    //进行IO sockfd->Recv()
                    //sockfd ->Send()
                    _handler(sockfd, inetaddr);
                    exit(0);
                }
                sockfd->Close();
                pid_t waitid = waitpid(id,nullptr,0);
                if(waitid == 0)
                {
                    LOG(LogLevel::ERROR)<<"回收父进程失败";
                }
            }
        }

    private:
        std::unique_ptr<Socket> _listensockfd;
        bool _isrunning;
        uint16_t _port;
        handler_t _handler;
    };

}